package network;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdpEchoServer {
    // 先定义一个 socket 对象
    // 需要网络通信，必须使用socket 对象
    private DatagramSocket socket = null;

    // 绑定一个端口，不一定能成功
    // 如果某个端口已经被别的占用 了，此时这里的绑定操作就会出错
    // 同一个主机上，一个端口，同一时刻，只能被一个进程绑定
    public UdpEchoServer(int port) throws SocketException {
        // 构造 socket 的同时，指定要关联/绑定的端口
        socket = new DatagramSocket(port);
    }

    // 启动服务器的主逻辑
    public void start() throws IOException {
        System.out.println("服务器启动");
        // 每次循环只干3件事
        while (true) {
            // 1.读取请求并解析
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);   // 构造一个饭盒
            socket.receive(requestPacket);  // 输出型此参数
            // 为了方便处理请求，将数据包转换成 String
            String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
            // 2. 根据请求计算响应
            String response = process(request);
            // 3. 把结果写回客户端
            // 和请求 packet 不同，此处构造响应的时候，需要指定这个包发给谁
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length,
                    // requestPacket 是从客户端这里收到的， getSocketAddress 就会获得客户端 ip 和 端口
                    requestPacket.getSocketAddress());
            socket.send(responsePacket);
            System.out.printf("[%s:%d] req: %s, resp: %s\n", requestPacket.getAddress().toString(),
                    requestPacket.getPort(), request, response);
        }
    }

    // 此处写的，回显程序;
    // 这是服务器中一个关键环节！
    public String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoServer udpEchoServer = new UdpEchoServer(9090);
        udpEchoServer.start();
    }


}
